Questions
1 of 14
1What is a segment in Qdrant's storage engine, and why does a collection consist of multiple segments rather than one monolithic index?
2What role does the Write-Ahead Log (WAL) play in Qdrant, and what failure scenario does it protect against?
3How does memory-mapped (mmap) storage allow Qdrant to serve a collection larger than available RAM?
4What does the background optimizer do in Qdrant, and why can too-aggressive optimization affect query latency?
5What is the practical difference between storing vectors in-memory versus on-disk in a collection configuration, and when would you choose on-disk?
6What is sharding in a distributed Qdrant cluster, and what determines which shard a given point is written to by default?
7What is custom sharding, and how does it change the way multitenant data is distributed across a cluster?
8What consensus algorithm does Qdrant use to keep cluster metadata consistent across nodes, and what does it coordinate?
9What are Qdrant's tunable read/write consistency levels for distributed operations, and what trade-off do they represent?
10In a replicated cluster, what happens to search results if a query is served while one replica of a shard is temporarily out of sync?
11Walk through what happens internally, at a high level, when a client sends a filtered vector search request to a distributed Qdrant cluster.
12Why does Qdrant merge and re-rank results from multiple shards rather than simply concatenating each shard's top-k?
13How does a payload filter interact with segment selection during query execution - does Qdrant always scan every segment?
14What is the performance implication of running a query that touches every named vector on a point versus one that specifies using?
01 / 14

What is a segment in Qdrant's storage engine, and why does a collection consist of multiple segments rather than one monolithic index?

A segment is the unit of indexing; a collection is many segments plus a WAL

A segment is the smallest independently indexed unit in Qdrant's storage engine. It holds a set of points, and it owns its own vector storage, payload storage, payload indexes, and HNSW graph. A collection is a logical container composed of one or more segments, plus a write-ahead log and the optimizer state that governs how segments are created, merged, and vacuumed. When you search a collection, the request fans out to every segment, each segment returns its local top-k, and the results are merged into a global top-k. A segment is not a shard - a shard is a distributed unit that can contain many segments, and a segment lives entirely within one shard on one node.

The reason for multiple segments is that an HNSW graph is very expensive to mutate in place. Inserting a point into a large graph means wiring new edges and potentially rewiring existing ones, which is both slow and concurrency-hostile. The LSM-style solution Qdrant uses is to make existing segments immutable and append new points to a small, fresh segment. That new segment is immediately searchable without touching the large graph. Periodically the optimizer merges several small segments into a larger one, building a single consolidated HNSW graph and payload index in the process, then atomically replaces the sources. This gives three things at once: concurrent writes (new data goes to a small mutable segment while readers query the stable ones), background optimization (merging is off the critical write path), and bounded per-write cost (you never rewire the whole graph on an upsert). The cost is fan-out: searching N segments means N graph traversals plus a merge, and each segment has fixed overhead for its indexes and file handles. So there is a sweet spot for segment count - too few and merges are expensive and writes stall, too many and every query pays fan-out overhead.

  1. 1

    Immutable by design: existing segments are never mutated in place; new points go to a small fresh segment that is later merged.

  2. 2

    Independently indexed: each segment has its own HNSW graph and payload indexes, so a query traverses each one separately and merges results.

  3. 3

    Optimizer-managed: the number and size of segments are governed by optimizer thresholds, not by the client.

  4. 4

    Deletes are tombstones: deleted points are marked and physically removed only during vacuuming, so a segment can contain deleted points until it is optimized.

  5. 5

    Not a shard: a segment is a single-node storage unit; a shard is a distributed unit that contains segments and can have replicas.

The trade-off is write throughput and concurrency against read fan-out and merge cost. More, smaller segments make writes fast and merges cheap but increase per-query overhead; fewer, larger segments make queries cheaper but make merges expensive and can stall ingest. The optimizer thresholds (default_segment_number, max_segment_size, indexing_threshold) are how you steer this. The common mistake is confusing segments with shards. Engineers new to Qdrant often assume that increasing shard_number will reduce per-segment cost, which is true at the cluster level, but segments within a shard are still governed by the optimizer and are not something you scale directly. The second common mistake is assuming that a delete immediately shrinks storage - it does not, the point is tombstoned until the segment is vacuumed, which is why deleted_threshold exists. The alternative to the segment model is a single mutable graph index, which some in-memory libraries use. It is simpler for read-only or low-churn data but performs poorly under high write rates, which is exactly why Qdrant did not choose it. Version note: the exact set of optimizer thresholds and their defaults have changed across releases, so read the effective config at runtime rather than hardcoding values from an older doc.

javascript

Version-dependent: the segments_count field and the optimizer_config shape have changed across Qdrant releases. The ability to inspect individual segments and their sizes is not exposed in all client versions - some releases only surface the aggregate count. Treat segment count as an emergent property you observe, not a parameter you set, and re-measure after any upgrade that touches the optimizer, because the defaults have shifted more than once.

Difficulty: 7/10
Topics: Storage Engine, Segments, Optimizer

Scenario Questions

0-2 years experience
  1. 1

    You upsert 1000 points into a fresh collection and query immediately. Explain what segment the points are in and whether the query touches an HNSW graph at all.

  2. 2

    A teammate says a collection with more segments will always be slower. Explain when that is true and when more segments actually helps.

2-5 years experience
  1. 1

    Your collection reports 40 segments at steady state and search latency is higher than expected. Walk through how you would reduce the segment count and what the impact on write throughput would be.

  2. 2

    You delete 30% of a collection and disk usage does not drop. Explain why and what you need to do to reclaim the space.

5-8 years experience
  1. 1

    Design an ingest and optimization strategy for a collection that receives 5k upserts per second continuously while serving 200 QPS of search. What optimizer thresholds would you set and why?

  2. 2

    You must run a one-time bulk load of 200M points and then switch to steady-state serving. Describe how you would change the optimizer configuration between the two phases and what signals tell you the load is complete.

8+ years experience
  1. 1

    Derive a model for the optimal number of segments as a function of ingest rate, query rate, and merge cost, and explain where the model breaks down for real workloads.

  2. 2

    You are designing a storage engine for a search system with the same constraints Qdrant faces. Would you choose the immutable-segment model or a mutable graph, and what workload characteristics would flip your decision?

Follow-up Questions

  • How would you diagnose whether a collection has too many segments versus too few, using only metrics and the collection config?
  • What happens to a point that is upserted twice - does the old version get tombstoned in the same segment, and how does the optimizer reconcile duplicate IDs across segments?